/*
 * Sistema Leilão de Câmbio - Módulo Web.
 *
 * Copyright (c) Banco Central do Brasil.
 *
 * Este software é confidencial e propriedade do Banco Central do Brasil.
 * Não é permitida sua distribuição ou divulgação do seu conteúdo sem
 * expressa autorização do Banco Central.
 * Este arquivo contém informações proprietárias.
 */
package br.gov.bcb.leilao.web.componentes;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.IMarkupCacheKeyProvider;
import org.apache.wicket.markup.IMarkupResourceStreamProvider;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.StringResourceStream;

import br.gov.bcb.leilao.web.enumeration.SortOrderEnum;

public class ComponentOrdenacao extends Panel implements IMarkupResourceStreamProvider, IMarkupCacheKeyProvider {

    private static final String ATTR_SRC = "src";
    private static final String ATTR_STYLE = "style";
    private static final String ATTR_TITLE = "title";

    private static final String IMG_ATIVAR_A = "/leilao/images/arrow-none.gif";
    private static final String IMG_CRESC_A = "/leilao/images/arrow-up.gif";
    private static final String IMG_DECRESC_A = "/leilao/images/arrow-down.gif";

    private static final String TITLE_ATIVAR_A = "Reordenar coluna";
    private static final String TITLE_CRESC_A = "Coluna em ordem crescente";
    private static final String TITLE_DECRESC_A = "Coluna em ordem descrescente";

    private static final AttributeModifier ATTR_IMG_ATIVAR_A = //
            new AttributeModifier(ATTR_SRC, true, new Model<String>(IMG_ATIVAR_A));
    private static final AttributeModifier ATTR_IMG_CRESC_A = //
            new AttributeModifier(ATTR_SRC, true, new Model<String>(IMG_CRESC_A));
    private static final AttributeModifier ATTR_IMG_DECRESC_A = //
            new AttributeModifier(ATTR_SRC, true, new Model<String>(IMG_DECRESC_A));

    private static final AttributeModifier ATTR_TITLE_ATIVAR_A = //
            new AttributeModifier(ATTR_TITLE, true, new Model<String>(TITLE_ATIVAR_A));
    private static final AttributeModifier ATTR_TITLE_CRESC_A = //
            new AttributeModifier(ATTR_TITLE, true, new Model<String>(TITLE_CRESC_A));
    private static final AttributeModifier ATTR_TITLE_DECRESC_A = //
            new AttributeModifier(ATTR_TITLE, true, new Model<String>(TITLE_DECRESC_A));

    private static final String WID_IMG_ORDENACAO = "imgOrdenacao";

    private MarkupContainer imgOrdenacao;

    private String nomeDaColuna;
    private String propertyDaColuna;
    private IComponentOrdenacaoListener iComponentOrdenacaoListener;

    public ComponentOrdenacao(String id, String nomeDaColuna, String propertyDaColuna,
            IComponentOrdenacaoListener iComponentOrdenacaoListener) {
        super(id);

        this.nomeDaColuna = nomeDaColuna;
        this.propertyDaColuna = propertyDaColuna;
        this.iComponentOrdenacaoListener = iComponentOrdenacaoListener;

        add(new AttributeModifier(ATTR_STYLE, true, new Model<String>("cursor: pointer;")));

        imgOrdenacao = new WebMarkupContainer(WID_IMG_ORDENACAO);
        imgOrdenacao.setOutputMarkupId(true);
        add(imgOrdenacao);

        add(new AjaxOnClick());

        setaEstadoPadraoDoIconeDaOrdenacao(this);
    }

    private void setaEstadoPadraoDoIconeDaOrdenacao(ComponentOrdenacao componentOrdenacao) {
        componentOrdenacao.add(ATTR_TITLE_ATIVAR_A);
        componentOrdenacao.getImgOrdenacao().add(ATTR_IMG_ATIVAR_A);
    }

    private SortOrderEnum alteraEstadoDoIconeDaOrdenacao(ComponentOrdenacao componentOrdenacao) {
        SortOrderEnum sortOrderEnum = SortOrderEnum.UNSORTED;

        if (componentOrdenacao.getImgOrdenacao().getBehaviors().contains(ATTR_IMG_ATIVAR_A)) {
            removeEstadoDoIconeDaOrdenacao(componentOrdenacao);
            componentOrdenacao.getImgOrdenacao().add(ATTR_IMG_CRESC_A);
            componentOrdenacao.add(ATTR_TITLE_CRESC_A);
            sortOrderEnum = SortOrderEnum.ASCENDING;
        } else if (componentOrdenacao.getImgOrdenacao().getBehaviors().contains(ATTR_IMG_CRESC_A)) {
            removeEstadoDoIconeDaOrdenacao(componentOrdenacao);
            componentOrdenacao.getImgOrdenacao().add(ATTR_IMG_DECRESC_A);
            componentOrdenacao.add(ATTR_TITLE_DECRESC_A);
            sortOrderEnum = SortOrderEnum.DESCENDING;
        } else if (componentOrdenacao.getImgOrdenacao().getBehaviors().contains(ATTR_IMG_DECRESC_A)) {
            removeEstadoDoIconeDaOrdenacao(componentOrdenacao);
            componentOrdenacao.getImgOrdenacao().add(ATTR_IMG_CRESC_A);
            componentOrdenacao.add(ATTR_TITLE_CRESC_A);
            sortOrderEnum = SortOrderEnum.ASCENDING;
        }

        return sortOrderEnum;
    }

    private void removeEstadoDoIconeDaOrdenacao(ComponentOrdenacao componentOrdenacao) {
        if (componentOrdenacao.getImgOrdenacao().getBehaviors().contains(ATTR_IMG_ATIVAR_A)) {
            componentOrdenacao.getImgOrdenacao().remove(ATTR_IMG_ATIVAR_A);
            componentOrdenacao.remove(ATTR_TITLE_ATIVAR_A);
        }
        if (componentOrdenacao.getImgOrdenacao().getBehaviors().contains(ATTR_IMG_CRESC_A)) {
            componentOrdenacao.getImgOrdenacao().remove(ATTR_IMG_CRESC_A);
            componentOrdenacao.remove(ATTR_TITLE_CRESC_A);
        }
        if (componentOrdenacao.getImgOrdenacao().getBehaviors().contains(ATTR_IMG_DECRESC_A)) {
            componentOrdenacao.getImgOrdenacao().remove(ATTR_IMG_DECRESC_A);
            componentOrdenacao.remove(ATTR_TITLE_DECRESC_A);
        }
    }

    protected MarkupContainer getImgOrdenacao() {
        return this.imgOrdenacao;
    }

    private class AjaxOnClick extends AjaxEventBehavior {

        public AjaxOnClick() {
            super(EventoAjax.ON_CLICK.toString());
        }

        @Override
        protected void onEvent(AjaxRequestTarget target) {
            SortOrderEnum sortOrderEnum = alteraEstadoDoIconeDaOrdenacao((ComponentOrdenacao) getComponent());

            resetaEstadoDosIconesDasOrdenacoesAnteriores();

            iComponentOrdenacaoListener.ordenaLista(propertyDaColuna, sortOrderEnum);

            target.addComponent(getPage(), getPage().getMarkupId());
        }

        private void resetaEstadoDosIconesDasOrdenacoesAnteriores() {
            getComponent().getParent().visitChildren(new IVisitor<Component>() {

                @Override
                public Object component(Component component) {
                    if (component instanceof ComponentOrdenacao && !component.equals(getComponent())) {
                        ComponentOrdenacao componentOrdenacao = (ComponentOrdenacao) component;

                        removeEstadoDoIconeDaOrdenacao(componentOrdenacao);

                        setaEstadoPadraoDoIconeDaOrdenacao(componentOrdenacao);
                    }
                    return null;
                }
            });
        }
    }

    @Override
    public IResourceStream getMarkupResourceStream(MarkupContainer container, Class<?> containerClass) {
        return new StringResourceStream(getCacheKey(container, containerClass));
    }

    @Override
    public String getCacheKey(MarkupContainer container, Class<?> containerClass) {
        StringBuilder sb = new StringBuilder();
        sb.append("<wicket:panel>\n");
        sb.append("  <div class=\"centralizado\">\n");
        sb.append("    <span>" + nomeDaColuna + "</span>\n");
        sb.append("    <img wicket:id=\"" + WID_IMG_ORDENACAO + "\"/>\n");
        sb.append("  </div>\n");
        sb.append("</wicket:panel>\n");
        return sb.toString();
    }
}
